●状態クラスの例(待機状態)
状態クラスの例として,「徘徊を中断させているとき」に対応する状態の実装方法を示します.
この状態は,
- ポップアップメニューで「箱入り猫」を選択されたらこの状態になる
- 「猫が箱に入った画像」が表示される
- 徘徊しない(ほっとくと,ずっと同じ場所)
- マウスドラッグで移動させることができる
ものとします.
ポップアップメニューから状態変更.
箱入り猫画像.
本当は「*はこのなかにいる*」まで描きたいのだが短縮系.足りない「にいる」については脳内補間で対応.
●OnCreate()
CDMManagerがこのクラスのオブジェクトを作ったときに呼びます.
猫ウィンドウクラスに箱入り猫のアニメーションを登録するだけです.(コード省略)
●OnSelect()
状態変更時に(CDMManager::ChangeState()内から)呼びます.
状態クラスはここで,猫ウィンドウに対して,自分用のアニメーションを選択させます.
また,その他の必要な設定(ポップアップメニュー項目のEnable,Disableとか)を行います.
箱入り猫状態では,ポップアップメニュー項目の「箱入り猫」項目にチェックをいれたりします.
void CDMState_InBox::OnSelect( CCatWnd *pCatWnd, class CDMManager *pManager ) { pCatWnd->SetBltMode( CCatWnd::BLT_NORMAL );//アニメーションを普通に描画する pCatWnd->EnablePopupMenuItem( MENU_ID_INBOX, true );//メニュー項目を有効に pCatWnd->CheckPopupMenuItem( MENU_ID_INBOX, true );//メニュー項目にチェックを入れる pCatWnd->SetCurAnimFrame( ANIM_ID_INBOX, 0 );//箱入り猫なアニメーションを選択する }CCatWnd::SetBltMode()は,画像を反転表示させたりするための設定用関数です.
(左右向き分の画像を用意するのが面倒なので::StretchBlt()で反転表示.)
●OnPreChangeAnimFrame()
アニメーションの切り替わり時の処理ですが,箱入り猫状態では,特にすることがないのでオーバーロードしません.
(デフォルト動作で,アニメーションがループ)
●OnPopupMenu()
ポップアップメニューへの対応です.
選択された項目が「箱入り猫」だった場合,この状態を抜けて「徘徊」状態に移行させます.bool CDMState_InBox::OnPopupMenu( CCatWnd *pCatWnd, class CDMManager *pManager, UINT ItemID ) { return pManager->ChangeState( pCatWnd, ANIM_ID_WALKA );//徘徊状態に切換え }「箱入り猫」メニュー項目のチェックを外したりするのは,徘徊状態クラス側のOnSelect()の仕事にしているので,単純に状態切換えをするだけです.
●OnOtherEvent()
その他のメッセージへの対応処理です.
箱入り猫状態では,ドラッグによる移動を可能にするためのコードを記述します.
コードは省略しますが,WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE で普通に処理しています.
なお,この処理のためにマウスキャプチャを行う必要に迫られ,既に「CCatWndにHWNDを返すメソッドを追加したくて仕方が無い」精神状態に追いやられています.
●動作骨組みはこれだけ.
個々の状態での処理は少しずつ異なるだけ(他の状態への遷移の条件等が違う)なので,ひとつ作れば増やすのは(コードのコピーとちょっとした修正で済むので)楽です.
CDMManagerクラスが状態クラスのメンバを適切なタイミングで呼ぶ部分ができているので,徘徊アプリケーションが動作する骨組み自体はほぼ出来上がりです.
一番の問題は,
状態(アニメパターン)を増やすためにはアニメーションの絵を描かなければならない
ということです.
あと,猫にカーソルを合わせると砂時計カーソルになる原因不明の現象が発生中.誰か助けて!
- Newer: 気まぐれ Programming TIPS 【1】
- Older: 徘徊アプリの動作骨組(1)